/* 
 * File:   printformoperation.cpp
 * Author: oli
 * 
 * Created on October 15, 2008, 5:17 PM
 */

#include "Device.h"


#include "Device.h"


#include "Device.h"


#include "PrintFormOperation.h"

#include "text.h"
#include  <string>

PrintFormOperation::PrintFormOperation() {
}

PrintFormOperation::~PrintFormOperation() {
}

Glib::RefPtr<PrintFormOperation> PrintFormOperation::create() {
    return Glib::RefPtr<PrintFormOperation > (new PrintFormOperation());
}

void PrintFormOperation::set_device(Device dev) {
    deviceToPrint = &dev;
}

void PrintFormOperation::on_begin_print(
        const Glib::RefPtr<Gtk::PrintContext>& print_context) {
    //Create and set up a Pango layout for PrintData based on the passed
    //PrintContext: We then use this to calculate the number of pages needed, and
    //the lines that are on each page.
    m_refLayout = print_context->create_pango_layout();

    Pango::FontDescription font_desc("sans 10");
    m_refLayout->set_font_description(font_desc);

    const double width = print_context->get_width();
    const double height = print_context->get_height();

    m_refLayout->set_width(static_cast<int> (width * Pango::SCALE));
    //Set and mark up the text to print:

    ///////////////////////////////
    //time, create extra function!!
    time_t t;
    time(&t);
    string time = ctime(&t);
    ///////////////////////////////

    Glib::ustring marked_up_form_text;
    marked_up_form_text += "<big>Created with <b>";
    marked_up_form_text += TITLE;
    marked_up_form_text += " - ";
    marked_up_form_text += VER;
    marked_up_form_text += "</b> on " + time + "</big>\n\n";
    if (!deviceToPrint->getBridge_chan_index().empty()) {
        marked_up_form_text += "<u><big>Bridge Information</big></u>\n";
        marked_up_form_text += "<b>Linux Devicename</b>: " +
                deviceToPrint->getDeviceName() + "\n";

        marked_up_form_text += "<b>Channel Index</b>: " +
                deviceToPrint->getBridge_chan_index() + "\n";
        marked_up_form_text += "<b>Channel Type</b>: " +
                deviceToPrint->getBridge_chan_type() + "\n";

        marked_up_form_text += "<b>Writes Permitted</b>: ";
        marked_up_form_text += (deviceToPrint->getBridge_writes_permitted() ? TP_YES : TP_NO);
        marked_up_form_text += "\n";

        marked_up_form_text += "<b>Declare Write Blocked</b>: ";
        marked_up_form_text += (deviceToPrint->getBridge_declare_write_blocked() ? TP_YES : TP_NO);
        marked_up_form_text += "\n";

        marked_up_form_text += "<b>Declare Write Errors</b>: ";
        marked_up_form_text += (deviceToPrint->getBridge_declare_write_errors() ? TP_YES : TP_NO);
        marked_up_form_text += "\n";

        marked_up_form_text += "<b>Bridge Serial</b>: " +
                deviceToPrint->getBridge_serial() + "\n";
        marked_up_form_text += "<b>Bridge Vendor</b>: " +
                deviceToPrint->getBridge_vendor() + "\n";
        marked_up_form_text += "<b>Bridge Model</b>: " +
                deviceToPrint->getBridge_model() + "\n";
        marked_up_form_text += "<b>Firmware Date</b>: " +
                deviceToPrint->getBridge_firmware_date() + "\n";
        marked_up_form_text += "<b>Firmware Time</b>: " +
                deviceToPrint->getBridge_firmware_time() + "\n\n";

        marked_up_form_text += "<u><big>Drive Information</big></u>\n";
        marked_up_form_text += "<b>Drive Vendor</b>: " +
                deviceToPrint->getBridge_drive_vendor() + "\n";
        marked_up_form_text += "<b>Drive Model</b>: " +
                deviceToPrint->getBridge_drive_model() + "\n";
        marked_up_form_text += "<b>Drive Serial</b>: " +
                deviceToPrint->getBridge_drive_serial() + "\n";
        marked_up_form_text += "<b>Drive Revision</b>: " +
                deviceToPrint->getBridge_drive_revision() + "\n";
        marked_up_form_text += "<b>Drive Size</b>: " +
                deviceToPrint->getSize() + "\n";
        marked_up_form_text += "<b>Drive BlockSize</b>: " +
                deviceToPrint->getBridge_drive_capacity() + "\n\n";

        marked_up_form_text += "<u><big>Drive HPA/DCO/Security Information</big></u>\n";
        marked_up_form_text += "<b>Security Support</b>: ";
        marked_up_form_text += (deviceToPrint->getBridge_security_support() ? TP_YES : TP_NO);
        marked_up_form_text += "\n";

        if (deviceToPrint->getBridge_security_support()) {
            marked_up_form_text += "<b>Security In Use</b>: ";
            marked_up_form_text += (deviceToPrint->getBridge_security_in_use() ? TP_YES : TP_NO);
            marked_up_form_text += "\n";
        }
        marked_up_form_text += "<b>HPA Support</b>: ";
        marked_up_form_text += (deviceToPrint->getBridge_hpa_support() ? TP_YES : TP_NO);
        marked_up_form_text += "\n";

        if (deviceToPrint->getBridge_hpa_support()) {
            marked_up_form_text += "<b>HPA In Use</b>: ";
            marked_up_form_text += (deviceToPrint->getBridge_hpa_in_use() ? TP_YES : TP_NO);
            marked_up_form_text += "\n";
            marked_up_form_text += "<b>HPA BlockSize</b>: " +
                    deviceToPrint->getBridge_hpa_capacity() + "\n";
        }
        marked_up_form_text += "<b>DCO Support</b>: ";
        marked_up_form_text += (deviceToPrint->getBridge_dco_support() ? TP_YES : TP_NO);
        marked_up_form_text += "\n";

        if (deviceToPrint->getBridge_dco_support()) {
            marked_up_form_text += "<b>DCO In Use</b>: ";
            marked_up_form_text += (deviceToPrint->getBridge_dco_in_use() ? TP_YES : TP_NO);
            marked_up_form_text += "\n";
            marked_up_form_text += "<b>DCO BlockSize</b>: " +
                    deviceToPrint->getBridge_dco_capacity() + "\n";
            marked_up_form_text += "<b>DCO Challenge Key</b>: " +
                    deviceToPrint->getBridge_dco_challenge_key() + "\n";
        }
        marked_up_form_text += "\n\n";


    }
    marked_up_form_text += "<u><big><b>Local Informations</b></big></u>\n";
   
    marked_up_form_text += "<b>Linux Devicename</b>: " + deviceToPrint->getDeviceName() + "\n";
    marked_up_form_text += "<b>Vendor</b>: " + deviceToPrint->getVendor() + "\n";
    marked_up_form_text += "<b>Model</b>: " + deviceToPrint->getModel() + "\n";
    marked_up_form_text += "<b>Size</b>: " + deviceToPrint->getSize() + "\n";
    marked_up_form_text += "<b>Blocksize</b>: " + deviceToPrint->getSizeBLK() + "\n";


    if (!deviceToPrint->getComment().empty()) {
        marked_up_form_text += "<u><big><b>Comments</b></big></u>\n";
        marked_up_form_text += deviceToPrint->getComment() + "\n";
    }

    m_refLayout->set_markup(marked_up_form_text);
    
    
    //Set the number of pages to print by determining the line numbers
    //where page breaks occur:
    const int line_count = m_refLayout->get_line_count();

    Glib::RefPtr<Pango::LayoutLine> layout_line;
    double page_height = 0;

    for (int line = 0; line < line_count; ++line) {
        Pango::Rectangle ink_rect, logical_rect;

        layout_line = m_refLayout->get_line(line);
        layout_line->get_extents(ink_rect, logical_rect);

        const double line_height = logical_rect.get_height() / 1024.0;

        if (page_height + line_height > height) {
            m_PageBreaks.push_back(line);
            page_height = 0;
        }

        page_height += line_height;
    }

    set_n_pages(m_PageBreaks.size() + 1);
}

void PrintFormOperation::on_draw_page(
        const Glib::RefPtr<Gtk::PrintContext>& print_context, int page_nr) {
    //Decide which lines we need to print in order to print the specified page:
    int start_page_line = 0;
    int end_page_line = 0;

    if (page_nr == 0) {
        start_page_line = 0;
    } else {
        start_page_line = m_PageBreaks[page_nr - 1];
    }

    if (page_nr < static_cast<int> (m_PageBreaks.size())) {
        end_page_line = m_PageBreaks[page_nr];
    } else {
        end_page_line = m_refLayout->get_line_count();
    }

    //Get a Cairo Context, which is used as a drawing board:
    Cairo::RefPtr<Cairo::Context> cairo_ctx = print_context->get_cairo_context();

    //We'll use black letters:
    cairo_ctx->set_source_rgb(0, 0, 0);

    //Render Pango LayoutLines over the Cairo context:
    Pango::LayoutIter iter;
    m_refLayout->get_iter(iter);

    double start_pos = 0;
    int line_index = 0;

    do {
        if (line_index >= start_page_line) {
            Glib::RefPtr<Pango::LayoutLine> layout_line = iter.get_line();
            Pango::Rectangle logical_rect = iter.get_line_logical_extents();
            int baseline = iter.get_baseline();

            if (line_index == start_page_line) {
                start_pos = logical_rect.get_y() / 1024.0;
            }

            cairo_ctx->move_to(logical_rect.get_x() / 1024.0,
                    baseline / 1024.0 - start_pos);

            layout_line->show_in_cairo_context(cairo_ctx);
        }

        line_index++;
    } while (line_index < end_page_line && iter.next_line());
}

